package cn.itcast.lucene;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.search.highlight.*;
import org.apache.lucene.search.highlight.Scorer;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;

import java.io.File;
import java.io.IOException;


public class IndexQuerySuperTest {

    /**
     * 高亮查询，先做普通查询，查询完后再做二次分词，分完后根据查询关键字来对比，在关键字前后进行拼接<em></em>
     *
     * @throws IOException
     * @throws ParseException
     */
    @Test
    public void highLightSearch() throws IOException, ParseException, InvalidTokenOffsetsException {
//      声明索引所在目录，进行搜索
        Directory directory = FSDirectory.open(new File("indexDir"));

//    创建一个读取对象来读取索引目录
        IndexReader indexReader = DirectoryReader.open(directory);

//    搜索对象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        QueryParser queryParser = new QueryParser("title", new IKAnalyzer());

        Query query = queryParser.parse("谷歌");


//    传入搜索条件以及需要得条目数，（前n个）有多少个显示多少，输出内容是需要的和命中的取小。抽取出来的n，最大值
        TopDocs topDocs = indexSearcher.search(query, Integer.MAX_VALUE);

//    命中得元素的个数
        int totalHits = topDocs.totalHits;
        System.out.println("命中的文档个数:" + totalHits);

//    得分文档数组
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;

//     准备高亮工具
        Formatter formatter = new SimpleHTMLFormatter("<em>","</em>");

        Scorer scorer = new QueryScorer(query);

        Highlighter highlighter = new Highlighter(formatter,scorer);

        for (ScoreDoc scoreDoc : scoreDocs) {
//    当前文档得分
            float score = scoreDoc.score;

//    文档编号
            int docId = scoreDoc.doc;

            Document document = indexSearcher.doc(docId);

//    根据文档id获取具体的文档
            String id = document.get("id");
            String result = document.get("title");

//            使用高亮工具进行二次分词，并做关键词的高亮匹配，
            String highlighterTitle = highlighter.getBestFragment(new IKAnalyzer(), "title", result);

            System.out.println("得分:" + score + " " + "id:" + id + " " + "title:" + highlighterTitle);
        }
    }

    @Test
    public void sortSearch() throws IOException, ParseException, InvalidTokenOffsetsException {
//      声明索引所在目录，进行搜索
        Directory directory = FSDirectory.open(new File("indexDir"));

//    创建一个读取对象来读取索引目录
        IndexReader indexReader = DirectoryReader.open(directory);

//    搜索对象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        QueryParser queryParser = new QueryParser("title", new IKAnalyzer());

        Query query = queryParser.parse("谷歌");

//        声明排序条件   一般不用String排，用id   默认是升序，reverse（反转）为true的话即为降序
        Sort sort=new Sort(new SortField("id",SortField.Type.LONG,true));

//    传入搜索条件以及需要得条目数，（前n个）有多少个显示多少，输出内容是需要的和命中的取小。抽取出来的n，最大值
        TopDocs topDocs = indexSearcher.search(query, Integer.MAX_VALUE,sort);

//    命中得元素的个数
        int totalHits = topDocs.totalHits;
        System.out.println("命中的文档个数:" + totalHits);

//    得分文档数组
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;

        for (ScoreDoc scoreDoc : scoreDocs) {
//    当前文档得分
            float score = scoreDoc.score;

//    文档编号
            int docId = scoreDoc.doc;

            Document document = indexSearcher.doc(docId);

//    根据文档id获取具体的文档
            String id = document.get("id");
            String result = document.get("title");

            System.out.println("得分:" + score + " " + "id:" + id + " " + "title:" + result);
        }
    }

}
